"""
Webassign backend

This file is part of polyglot, etc.
"""

import datetime
import json
import re
from backends.support import Backend, Course, ResourceCategory, ResourceRawHTML, Task, Quiz, MultipartQuestion, MultipleChoiceQuestion, FreeResponseQuestion
import requests
from lxml.html import parse
from io import StringIO

class WebassignMC(MultipleChoiceQuestion):
    def __init__(self, prompt, options, unique):
        self.prompt = prompt
        self.options = options
        self.unique = unique

class WebassignFRQ(FreeResponseQuestion):
    def __init__(self, prompt, id, short):
        self.prompt = prompt
        self.id = id
        self.short = short

class WebassignQuiz(Quiz):
    def __init__(self, backend, page):
        super().__init__(id, name)
        self.backend = backend
        self.page = page

    def parse_question(self, question):
        labels = { x.attrib["for"]: x.text for x in question.cssselect("label")}

        current_prompt = ""
        in_multi_input = False
        radio = False
        options = []
        parts = []

        for child in question.iter():
            if in_multi_input and not (child.tag in ["label", "span", "br"] or (child.tag == "input" and child.attrib["type"] in ["checkbox", "radio"])):
                parts += [WebassignMC(current_prompt, options, radio)]

                in_multi_input = False
                options = []
                current_prompt = ""

            if child.tag != "label":
                if not isinstance(child, HtmlComment):
                    current_prompt += child.text.strip() if child.text else ""

                current_prompt += child.tail.strip() if child.tail else ""

            if child.tag == "input":
                if child.attrib["type"] in ["checkbox", "radio"]:
                    radio = child.attrib["type"] == "radio"
                    in_multi_input = True
                    options += [(child.name, labels[child.attrib["id"]])]
                elif child.attrib["type"] == "text":
                    parts += [WebassignFRQ(current_prompt, child.name, True)]
                    current_prompt = ""
            elif child.tag == "textarea":
                parts += [WebassignFRQ(current_prompt, child.name, False)]
                current_prompt = ""

        return parts

    def questions(self):
        questions = []

        for box in self.page.cssselect(".studentQuestionBox"):
            parts = []
            questions += [MultipartQuestion(parse_question(box))]

        return questions

    def submit(self, responses):
        return True

class WebassignTask(Task):
    def __init__(self, backend, name, dep):
        self.name = name
        self.backend = backend
        self.dep = dep
        self.due_date = None # TODO

    @property
    def page(self):
        imm = self.backend.session.get("http://www.webassign.net/web/Student/Assignment-Responses/last", data = {"dep": self.dep})
        return parse(StringIO(imm.text)).getroot()

    @property
    def resources(self):
        return [WebassignQuiz(self.backend, self.page)]

class WebassignCourse(Course):
    def __init__(self, c_id, tasks):
        self.id = c_id
        self.tasks = tasks

        self.title = "Unknown"
        self.teacher = "Unknown"

class WebassignBackend(Backend):
    Config = ["Username", "Password"]

    def login(self, config):
        sso = self.session.post("https://www.webassign.net/web/auth/login/sso", json = {
            "uid": config["Username"],
            "password": config["Password"]
        })

        response = json.loads(sso.text)

        token = response["result"]["token"]
        
        imm = self.session.get("https://www.webassign.net/v4cgi/login.pl", data = {"token": token})
        next_url = re.search("externalRedirect\('([^']*)'\)", imm.text, re.MULTILINE).group(1)

        self.portal = parse(StringIO(self.session.get(next_url).text)).getroot()

        return True

    @property
    def current_assignments(self):
        asn = []

        for task in self.portal.cssselect(".rowLeft")[1]:
            name = task.text
            (_, dep) = re.match("follow_link\('(.*)', (.*)\)", task.attrib["onclick"]).groups()
            asn += [WebassignTask(self, name, dep)]
            print((name, dep))

        return asn

    @property
    def courses(self):
        return [WebassignCourse("Aggregate", self.current_assignments)]
